package com.example.ditie2.task;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.ditie2.dto.Profile;
import com.example.ditie2.dto.TokenData;
import com.example.ditie2.utils.MailU;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class Dtask  {

    @Autowired
    Profile profile;

    //抢票确认
    private Boolean isReservation = true;

    //初始化数据
    public Dtask(){

        //检查今天是否需要抢票
        checkTomorrowIsHoliday();

        //检查下token
//        checkToken();

        //12点抢票
//        startReservation();

        //八点抢票
//        startReservationByEigth();
    }

    /**
     * 检查今天是否需要抢票
     */
    @Scheduled(cron = "00 00 09 * * ?")
    public void checkTomorrowIsHoliday(){
        String res = HttpUtil.get("https://tool.bitefu.net/jiari/?d=" + DateUtil.tomorrow().toString("yyyyMMdd"));
        System.out.println("检查一下明天是不是假期: " + res);
        if ("0".equals(res)){
            System.out.println("嘤嘤嘤明天要上班，还是需要抢票滴！！");
            isReservation = true;
        }else{
            System.out.println("明个放假，不用抢票啦！！");
            isReservation = false;
        }
    }

    /**
     * 检查token是否过期
     */
    @Scheduled(cron = "0 0 14 * * ? ")
    public void checkToken(){

        int threadCount = 10;

        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        for (TokenData tokenData : profile.getTokenList()) {
            executor.submit(new tokenTask(tokenData));
        }

        executor.shutdown();
    }


    /**
     *  抢票执行类
     */
    @Scheduled(cron = "0 00 12 * * ? ")
    public void startReservation(){
        if (!isReservation) {
            return;
        }

        int threadCount = 10;

        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        for (TokenData tokenData : profile.getTokenList()) {
            executor.submit(new TicketTask(tokenData));
        }

        executor.shutdown();
    }

    /**
     *  抢票执行类
     */
    @Scheduled(cron = "0 00 20 * * ? ")
    public void startReservationByEigth(){
        if (!isReservation) {
            return;
        }

        int threadCount = 10;

        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        for (TokenData tokenData : profile.getTokenList()) {
            executor.submit(new TicketTask(tokenData));
        }

        executor.shutdown();
    }


    /**
     *  抢票执行类
     */
    private static class TicketTask implements Runnable{

        @Autowired
        private TokenData tokenData;

        public TicketTask(TokenData tokenData) {
            this.tokenData = tokenData;
        }

        @Override
        public void run() {

            boolean flag = false;
            int count = 0;

            JSONObject param = new JSONObject();
            param.set("lineName", "昌平线");
            param.set("snapshotWeekOffset", 0);
            param.set("stationName", "沙河站");
            param.set("enterDate", DateUtil.tomorrow().toString("yyyyMMdd"));
            param.set("snapshotTimeSlot", "0630-0930");
            param.set("timeSlot", tokenData.getTime());

            System.out.println("地铁预约参数组装完成"+ param);

            while (count < 5 && !flag){
                System.out.println(LocalDateTime.now() + ": 第"+(count+1)+"次请求预约接口");
                String resultStr = HttpRequest.post("https://webapi.mybti.cn/Appointment/CreateAppointment")
                        .header(Header.AUTHORIZATION, tokenData.getAuthorization())
                        .header(Header.CONTENT_TYPE, "application/json;charset=UTF-8")
                        .header("user-agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1")
                        .body(param.toString())
                        .timeout(10000)
                        .execute().body();
                System.out.println(LocalDateTime.now() + ": 第"+(count+1)+"次预约结果返回值为："+resultStr);
                if (resultStr != null){
                    JSONObject res;
                    try {
                        res = JSONUtil.parseObj(resultStr);
                        if (null != res.get("balance")){
                            if ((Integer)res.get("balance") > 0){
                                System.out.println(LocalDateTime.now() + ": 恭喜您第"+(count+1)+"次预约成功，明天不用排队啦！");
                                flag = true;
                            }
                        }else{
                            System.out.println(LocalDateTime.now() + ": 第"+(count+1)+"次预约失败");
                        }
                    } catch (Exception e) {
                        System.out.println(LocalDateTime.now() + ": 第"+(count+1)+"次预约失败；" + "原因：异常【" + e.getMessage() + "】");
                    }
                }else{
                    System.out.println(LocalDateTime.now() + ": 第"+(count+1)+"次预约失败");
                }
                count++;
            }

            if (flag){
                MailU.sendResMail(tokenData.getEmail(), tokenData.getName() + "的预约成功！","");
            }else{
                MailU.sendResMail(tokenData.getEmail(), tokenData.getName() + "的预约失败！","");
            }

            System.out.println(LocalDateTime.now() + ": 定时任务执行完成");
        }
    }


    /**
     *  token 检查类
     */
    private  class tokenTask implements Runnable{

        @Autowired
        private TokenData tokenData;

        public tokenTask(TokenData tokenData) {
            this.tokenData = tokenData;
        }

        @Override
        public void run() {
            String aToken = Base64.decodeStr(tokenData.getAuthorization());
            String[] aTokens = aToken.split(",");
            DateTime tokenTime = new DateTime(Long.parseLong(aTokens[1]));
            LocalDateTime tokenRxpireTime = LocalDateTimeUtil.of(tokenTime);
            DateTime dateTime = new DateTime(DateUtil.tomorrow().toString("yyyy-MM-dd") + " 23:59:59", DatePattern.NORM_DATETIME_FORMAT);
            LocalDateTime reservationTime = LocalDateTimeUtil.of(dateTime);
            if (tokenRxpireTime.isBefore(reservationTime)){
                System.out.println(tokenData.getName() + "的token将在一天后过期，请尽快修改！");
                MailU.sendMail(tokenData.getEmail(), tokenData.getName() + "的token将在一天后过期，请尽快修改！");
            }else {
                System.out.println(tokenData.getName() + "token检查完成，未过期！");
            }
            System.out.println(tokenData.getName() + "Token过期时间：" + tokenRxpireTime);
        }
    }
}


